# -*-coding:utf-8-*-
'''

4.declaration:
    > extern    > type specifier  > dec_list  > ;

/* 指针，数组，变量， 函数... */
8.dec_list:
    > declarator    >
    < ,             <

9.declarator:
    > identifier                                    >
    > ( > declarator    > )                         >
    > * > declarator                                >
    > declarator    > ( > )                         >
    > declarator    > [ >>>>>>>>>>>>>>>>>>>>>>> ]   >
                        > constant expression >

'''
import model
import re
from c_code_base_analyzer import eat_units, print_comment, is_a_name
from c_code_base_analyzer import c_code_reader


class declaration_anlyzer(c_code_reader):
    def is_function_declaration(self, line_left):
        if line_left.find('(') >= 0:
            return is_a_name(line_left[:line_left.find('(')].strip())

    def declaration_anlyze(self, line):
        if self.compile_flag is True and line != "":
            line_left = line
            # if self.current_state == "":
            is_declaration = False
            line_left, is_declaration = eat_units(line_left.strip(), "extern")
            line_left = self.key_word_filter(line_left)
            line_left, result = eat_units(line_left, "static")
            line_left, result = eat_units(line_left, "inline")
            line_left, result = eat_units(line_left, "__inline")
            '''
            to add key words to describe a declaration
            '''
            line_left, result, type_name = self.find_type(line_left)
            if result is True and not self.is_function_declaration(line_left):
                if is_declaration:
                    if line_left.find(';') > 0:
                        if line_left.find(',') < 0:
                            self.module_info.declaration_list.append(
                                line_left[:line_left.find(';')])
                            self.e_data_is_found = True
                            self.e_data_type_tmp = type_name
                            self.module_info.e_datas_in_module.append(
                                line.replace('extern', '').strip())
                            return line_left
                        else:
                            for dec in line_left[:line_left.find(';')].split(
                                    ','):
                                if dec != "":
                                    self.module_info.declaration_list.append(
                                        dec)
                        print_comment("parameter declaration")
                        self.current_handler = None

                    else:
                        self.crashed = True
                        print_comment("line error")
                    return ""

                else:
                    if not self.is_in_function:
                        self.e_data_is_found = True
                        self.e_data_type_tmp = type_name
                        if self.module_info.module_name == self.current_path:
                            self.module_info.e_datas_in_module.append(
                                line.replace('static', '').strip())
                        return line_left
                    else:
                        return line

            elif result is True:
                name = line_left[:line_left.find('(') + 1].strip()
                if re.findall(r'([a-zA-Z0-9_\t]+)\(', name.replace(" ",
                                                                   "")) != []:
                    if line_left[-1] == ';':
                        '''
                        function declaration
                        '''
                        self.module_info.declaration_list.append(
                            line_left[:line_left.find('(')].strip())
                        self.module_info.func_dec_list.append({
                            "dec_name":
                            line_left[:line_left.find('(')].replace(
                                '*', '').strip(),
                            "line":
                            line.replace('static', '').strip()
                        })

                        self.current_handler = None
                        print_comment("function declaration")
                        return ""
                    else:
                        '''
                        we found it is in a function now.
                        so wait for function anlyzer.
                        '''
                        self.is_in_function = True
                        self.function_line = line
                        self.function_tmp = model.func_info(
                            name=line_left[:line_left.find('(')].strip(),
                            ret_type=type_name)
                        self.unit_handled = True
                        return line_left[line_left.find('(') + 1:]
        return line
